package dongze.com.ckdj.adapter;

import android.databinding.DataBindingUtil;
import android.databinding.Observable;
import android.databinding.ViewDataBinding;
import android.support.annotation.CallSuper;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import dongze.com.ckdj.R;
import dongze.com.ckdj.databinding.MassLossEnclosureCheckboxItemBinding;
import dongze.com.ckdj.databinding.MassLossEnclosureEditItemBinding;
import dongze.com.ckdj.databinding.model.EnclosureItemCheckBoxModel;
import dongze.com.ckdj.databinding.model.EnclosureItemEditModel;
import dongze.com.ckdj.util.MyLog;

/**
 * Created by renxiaoxiao on 2017/8/18.
 */

public class EnclosureAdapter extends BaseAdapter {
    private static final String TAG = "EnclosureAdapter";
    private List<EnclosureListItem> mList;
    Map<String, String> values;

    public EnclosureAdapter(List<EnclosureListItem> list) {
        this(list, null);
    }

    public EnclosureAdapter(List<EnclosureListItem> list, Map<String, String> values) {
        this.mList = list;

        if (values != null) {
            this.values = values;
        } else {
            this.values = new HashMap<>(list.size());
        }
    }

    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return mList.get(position).getType().ordinal();
    }

    @Override
    public int getViewTypeCount() {
        return TypedListItem.Type.values().length;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        MyLog.i(TAG, "getView: " + position + " " + mList.get(position).getType().toData());
        switch (mList.get(position).getType()) {
            case CHECKBOX:
                convertView = getCheckBoxItemView(position, convertView, parent);
                break;
            case EDITTEXT:
                convertView = getEditTextItemView(position, convertView, parent);
                break;
        }

        Holder holder = (Holder) convertView.getTag();
        holder.bind(mList.get(position));
        return convertView;
    }

    private View getEditTextItemView(int position, View convertView, ViewGroup parent) {
        if (convertView == null || ((Holder) convertView.getTag()).type != mList.get(position).type) {
            MassLossEnclosureEditItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.mass_loss_enclosure_edit_item, null, false);
            convertView = binding.getRoot();
            EditHolder holder = new EditHolder();
            holder.type = mList.get(position).type;
            holder.bindingComponent = binding;
            binding.setEnclosure(holder.model);
            convertView.setTag(holder);
        }

        return convertView;
    }

    private View getCheckBoxItemView(int position, View convertView, ViewGroup parent) {
        if (convertView == null || ((Holder) convertView.getTag()).type != mList.get(position).type) {
            MyLog.i(TAG, "getCheckBoxItemView: " + position);
            MassLossEnclosureCheckboxItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.mass_loss_enclosure_checkbox_item, null, false);
            convertView = binding.getRoot();
            CheckBoxHolder holder = new CheckBoxHolder();
            holder.type = mList.get(position).type;
            holder.bindingComponent = binding;
            binding.setEnclosure(holder.model);
            convertView.setTag(holder);
        }
        return convertView;
    }

    private int getIndex(String str) {
        for (EnclosureListItem item :
                mList) {
            if (TextUtils.equals(item.getChText(), str))
                return item.sort;
        }

        return 0;
    }

    public String[] buildReason() {
        String[] reason = new String[2];
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();

        Map.Entry<String, String>[] arr = new Map.Entry[values.size()];
        values.entrySet().toArray(arr);
        Arrays.sort(arr, new Comparator<Map.Entry<String, String>>() {
            @Override
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return getIndex(o1.getKey()) - getIndex(o2.getKey());
            }
        });

        for (Map.Entry<String, String> entry :
                arr) {
            EnclosureListItem item = getItem(entry.getKey());

            if (item == null)
                continue;

            if (item.type == EnclosureListItem.Type.CHECKBOX) {
                sb1.append(entry.getKey());
                sb2.append((String) entry.getValue());
            } else if (item.type == EnclosureListItem.Type.EDITTEXT) {
                sb1.append(entry.getKey());
                sb1.append("(" + entry.getValue() + ")");
                sb2.append(item.enText);
//                sb2.append("(" + entry.getValue() + ")");
            }

            sb1.append("-");
            sb2.append("-");
        }

        if (sb1.toString().endsWith("-"))
            sb1.deleteCharAt(sb1.lastIndexOf("-"));
        if (sb2.toString().endsWith("-"))
            sb2.deleteCharAt(sb2.lastIndexOf("-"));

        MyLog.i(TAG, "buildChReason: 中文:" + sb1.toString() + " 英文:" + sb2.toString());
        reason[0] = sb1.toString();
        reason[1] = sb2.toString();
        return reason;
    }

    private EnclosureListItem getItem(String chText) {
        for (EnclosureListItem item :
                mList) {
            if (TextUtils.equals(item.chText, chText))
                return item;
        }

        return null;
    }

    class Holder<T extends ViewDataBinding> {
        EnclosureListItem item;
        EnclosureListItem.Type type;
        T bindingComponent;

        @CallSuper
        public void bind(EnclosureListItem item) {
            this.item = item;
        }
    }

    class CheckBoxHolder extends Holder<MassLossEnclosureCheckboxItemBinding> {
        EnclosureItemCheckBoxModel model = new EnclosureItemCheckBoxModel();

        CheckBoxHolder() {
            model.check.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
                @Override
                public void onPropertyChanged(Observable sender, int propertyId) {
                    MyLog.i(TAG, "onPropertyChanged: ");
                    if (model.check.get()) {
                        values.put(item.chText, item.enText);
                    } else {
                        values.remove(item.chText);
                    }
                    notifyDataSetChanged();
                }
            });
        }

        @Override
        public void bind(EnclosureListItem item) {
            super.bind(item);
            model.text.set(item.chText);
            model.check.set(!TextUtils.isEmpty(values.get(item.chText)));
            bindingComponent.setEnclosure(model);
        }
    }

    class EditHolder extends Holder<MassLossEnclosureEditItemBinding> {
        EnclosureItemEditModel model = new EnclosureItemEditModel();

        EditHolder() {
            model.edit.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
                @Override
                public void onPropertyChanged(Observable sender, int propertyId) {
                    values.put(item.chText, model.edit.get());
                }
            });
        }

        @Override
        public void bind(EnclosureListItem item) {
            super.bind(item);
            model.text.set(item.chText);
            model.edit.set(values.get("其他"));
            bindingComponent.setEnclosure(model);
        }
    }
}
